package com.ajx.blog.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ajx.blog.service.impl.ChatAuthenticationFailureHandler;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

@Configuration
public class MySpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private ChatAuthenticationFailureHandler chatAuthenticationFailureHandler;

    @Bean
    PasswordEncoder passwordEncoder() {
        // 不对密码进行加密(在springsecurity5中默认需要进行密码加密)
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 用户
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        http.formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                .usernameParameter("aphone") // 指定自定义的登录页面用户名
                .passwordParameter("apass") // 指定自定义的登录页面密码
                .successHandler(new SimpleUrlAuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                            HttpServletResponse httpServletResponse, Authentication authentication)
                            throws IOException, ServletException {

                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        ServletOutputStream out = httpServletResponse.getOutputStream();
                        ObjectMapper objectMapper = new ObjectMapper();
                        returnMap.put("code", 0);
                        returnMap.put("data", null);
                        returnMap.put("msg", "登录成功");
                        logger.info(
                                "[SUCCESS]:调用了登陆方法,登陆成功-"
                                        + SecurityContextHolder.getContext().getAuthentication().getPrincipal());
                        objectMapper.writeValue(out, returnMap);
                        out.flush();
                        out.close();
                    }
                })
                .failureHandler(chatAuthenticationFailureHandler);

        // 注销登录
        http.logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/")
                .clearAuthentication(true)
                .invalidateHttpSession(true);

        // 关闭csrf
        http.csrf().disable();
        // 可以使用ifream框架
        http.headers().frameOptions().sameOrigin();
        // 自定义无权限页面(无权限跳转到自定义403页面)
        http.exceptionHandling().accessDeniedPage("/error.html");

    }

}
